/*
 * Hibiscus is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * Hibiscus is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Hibiscus; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * Copyright (C) 2003 Tetete - http://tetete.hu.
 */
package hu.tetete.hibiscus.edittaxon;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

import hu.tetete.hibiscus.dal.PropertyDao;
import hu.tetete.hibiscus.dal.TaxonDao;
import hu.tetete.hibiscus.dal.TaxonDatabaseOpenHelper;
import hu.tetete.hibiscus.model.Taxon;
import hu.tetete.hibiscus.model.TaxonLevel;
import hu.tetete.hibiscus.propertytree.PropertyTreeService;
import hu.tetete.hibiscus.propertyvalue.PropertyValue;
import hu.tetete.hibiscus.userfile.UserfileUtil;

/**
 * TODO javadoc.
 */
public class EditTaxonService extends PropertyTreeService {


    private final EditTaxonServiceBinder binder      = new EditTaxonServiceBinder();
    private final PropertyDao            propertyDao;
    private final TaxonDao               taxonDao;

    private Long                         id;
    private String                       name;
    private String                       scienceName;
    private TaxonLevel                   taxonLevel;
    private Taxon                        parentTaxon;
    private File                         photo;
    private boolean                      tempPhoto;
    private HashMap<Long, PropertyValue> values      = new HashMap<Long, PropertyValue>();

    /**
     * Constructor.
     */
    public EditTaxonService() {
        final TaxonDatabaseOpenHelper databaseOpenHelper = new TaxonDatabaseOpenHelper(this);
        this.propertyDao = new PropertyDao(databaseOpenHelper);
        this.taxonDao    = new TaxonDao(databaseOpenHelper);
    }

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class EditTaxonServiceBinder extends Binder {

        /**
         * @return Returns the newTaxonService instance.
         */
        public EditTaxonService getService() {
            // Return this instance of LocalService so clients can call public methods
            return EditTaxonService.this;
        }
    }


    /**
     * @see android.app.Service#onBind(android.content.Intent)
     */
    @Override
    public IBinder onBind(final Intent intent) {
        return this.binder;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return this.id;
    }
    /**
     * @param id the id to set
     */
    public void setId(final Long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return this.name;
    }

    /**
     * @param name the name to set
     */
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * @return the scienceName
     */
    public String getScienceName() {
        return this.scienceName;
    }

    /**
     * @param scienceName the scienceName to set
     */
    public void setScienceName(final String scienceName) {
        this.scienceName = scienceName;
    }

    /**
     * @return the taxonLevel
     */
    public TaxonLevel getTaxonLevel() {
        return this.taxonLevel;
    }

    /**
     * @param taxonLevel the taxonLevel to set
     */
    public void setTaxonLevel(final TaxonLevel taxonLevel) {
        this.taxonLevel = taxonLevel;
    }

    /**
     * @return the parentTaxon
     */
    public Taxon getParentTaxon() {
        return this.parentTaxon;
    }

    /**
     * @param parentTaxon the parentTaxon to set
     */
    public void setParentTaxon(final Taxon parentTaxon) {
        this.parentTaxon = parentTaxon;
    }

    /**
     * @return the photo file.
     */
    public File getPhoto() {
        return photo;
    }

    /**
     * @param the photo file.
     * @param if <tt>true</tt>, the photo file will be copied to the taxon's directory and will be removed.
     */
    public void setPhoto(final File photo, final boolean tempPhoto) {
        this.photo     = photo;
        this.tempPhoto = tempPhoto;
    }

    /**
     * @return the values
     */
    @Override
    public HashMap<Long, PropertyValue> getValues() {
        return this.values;
    }

    /**
     * @param values the values to set
     */
    public void setValues(final HashMap<Long, PropertyValue> values) {
        this.values = values;
    }

    /**
     * TODO javadoc.
     */
    public void reset() {
        this.values.clear();
        this.id          = null;
        this.parentTaxon = null;
        this.name        = null;
        this.scienceName = null;
        this.taxonLevel  = null;
        this.photo       = null;
        this.tempPhoto   = false;
    }

    /**
     * Sets the values by a taxon values.
     * @param taxon The taxon
     */
    public void initiateByTaxon(final Taxon taxon) {
        reset();
        if (taxon != null) {

            this.id          = taxon.getId();
            this.parentTaxon = this.taxonDao.getById(taxon.getParentId());
            this.name        = taxon.getName();
            this.scienceName = taxon.getScienceName();
            this.taxonLevel  = taxon.getTaxonLevel();
            this.values      = this.taxonDao.getPropertyValues(taxon.getId());
            this.photo       = UserfileUtil.getTaxonPhoto(taxon);
            this.tempPhoto   = false;

        }

    }

    /**
     * @see PropertyTreeService#removeValue(java.lang.Long)
     */
    @Override
    public boolean removeValue(final Long propertyId) {
        final boolean result = this.values.containsKey(propertyId);
        this.values.remove(propertyId);
        return result;
    }

    /**
     * @see PropertyTreeService#putValue(java.lang.Long, hu.tetete.hibiscus.propertyvalue.PropertyValue)
     */
    @Override
    public void putValue(final Long propertyId, final PropertyValue value) {
        this.values.put(propertyId, value);
    }

    /**
     * @see PropertyTreeService#getValue(java.lang.Long)
     */
    @Override
    public PropertyValue getValue(final Long propertyId) {
        return this.values.get(propertyId);
    }

    /**
     * @see PropertyTreeService#getPropertyDao()
     */
    @Override
    public PropertyDao getPropertyDao() {
        return this.propertyDao;
    }

    /**
     * Saves the taxon and returns the new taxon entity.
     * @return The new taxon entity
     * @throws IOException If the photo can't be saved.
     */
    public Taxon save() throws IOException {
        final Long newTaxonId = this.taxonDao.saveTaxon(this.id, this.name, this.scienceName, this.parentTaxon, this.taxonLevel, this.values);
        if (photo != null && tempPhoto) {
            final String photoFilename = UserfileUtil.savePhoto(photo, newTaxonId);
            taxonDao.saveTaxonPhoto(newTaxonId, photoFilename);
        }

        final Taxon taxon = this.taxonDao.getById(newTaxonId);
        return taxon;
    }


}
